package com.kmxd.ams.app.archive;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kmxd.ams.client.archive.IArchiveMetaFieldDetailSvc;
import com.kmxd.ams.client.archive.IArchiveMetaFieldMainSvc;
import com.kmxd.ams.client.archive.dto.*;
import com.kmxd.ams.client.archive.vo.ArchiveMetaFieldMainListVO;
import com.kmxd.ams.client.archive.vo.ArchiveMetaFieldMainVO;
import com.kmxd.ams.core.common.constant.ErrorCode;
import com.kmxd.ams.core.common.enums.DelFlagEnum;
import com.kmxd.ams.core.common.query.QueryGen;
import com.kmxd.ams.core.exception.BizTipException;
import com.kmxd.ams.core.util.ConvertUtil;
import com.kmxd.ams.core.util.IdUtil;
import com.kmxd.ams.infra.archive.entity.ArchiveMetaFieldDetail;
import com.kmxd.ams.infra.archive.entity.ArchiveMetaFieldMain;
import com.kmxd.ams.infra.archive.mapper.ArchiveMetaFieldMainMapper;
import java.util.*;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 元数据对应 服务实现类
 *
 * @author nickbi
 * @since 2022-07-23
 */
@Service
@AllArgsConstructor
public class ArchiveMetaFieldMainSvcImpl
    extends ServiceImpl<ArchiveMetaFieldMainMapper, ArchiveMetaFieldMain>
    implements IArchiveMetaFieldMainSvc {

  private ArchiveMetaFieldMainMapper archiveMetaFieldMainMapper;
  private IArchiveMetaFieldDetailSvc archiveMetaFieldDetailSvc;

  @Override
  public Page<ArchiveMetaFieldMainListVO> selectPage(
      Page reqPage, ArchiveMetaFieldMainQueryDTO req) {
    LambdaQueryWrapper<ArchiveMetaFieldMain> queryWrapper =
        QueryGen.init(new QueryWrapper<ArchiveMetaFieldMain>(), req).lambda();
    Page<ArchiveMetaFieldMain> page = archiveMetaFieldMainMapper.selectPage(reqPage, queryWrapper);
    Page<ArchiveMetaFieldMainListVO> voPage = BeanUtil.copyProperties(page, Page.class);
    voPage.setRecords(BeanUtil.copyToList(page.getRecords(), ArchiveMetaFieldMainListVO.class));
    return voPage;
  }

  @Override
  public List<ArchiveMetaFieldMainListVO> selectList(ArchiveMetaFieldMainQueryDTO req) {
    LambdaQueryWrapper<ArchiveMetaFieldMain> queryWrapper =
        QueryGen.init(new QueryWrapper<ArchiveMetaFieldMain>(), req).lambda();
    List<ArchiveMetaFieldMain> list = archiveMetaFieldMainMapper.selectList(queryWrapper);
    return BeanUtil.copyToList(list, ArchiveMetaFieldMainListVO.class);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void add(ArchiveMetaFieldMainAddDTO req) {
    // 检查设置是否存在
    LambdaQueryWrapper<ArchiveMetaFieldMain> wrapper =
        Wrappers.<ArchiveMetaFieldMain>lambdaQuery()
            .eq(ArchiveMetaFieldMain::getSourceTableId, req.getSourceTableId())
            .eq(ArchiveMetaFieldMain::getTargetArchTypeId, req.getTargetArchTypeId())
            .eq(ArchiveMetaFieldMain::getDelFlag, DelFlagEnum.NO.getCode());
    ArchiveMetaFieldMain exist = getOne(wrapper);
    if (null != exist) {
      BizTipException.throwException(ErrorCode.ARCHIVE_DATA_EXIST, "设置已存在");
    }
    // 保存元数据对应设置信息
    ArchiveMetaFieldMain entity = BeanUtil.copyProperties(req, ArchiveMetaFieldMain.class);
    archiveMetaFieldMainMapper.insert(entity);

    // 保存元数据对应字段信息
    List<ArchiveMetaFieldDetailAddDTO> fieldList = req.getFieldList();
    fieldList.forEach(f -> f.setFieldMainId(entity.getId()));
    List<ArchiveMetaFieldDetail> fieldDetailList =
        ConvertUtil.toList(fieldList, ArchiveMetaFieldDetail.class);
    archiveMetaFieldDetailSvc.saveBatch(fieldDetailList);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void edit(ArchiveMetaFieldMainEditDTO req) {
    // 检查设置是否存在
    ArchiveMetaFieldMain exist = getById(req.getId());
    if (null == exist) {
      BizTipException.throwException(ErrorCode.ARCHIVE_DATA_NOT_EXIST, "设置不存在");
    }
    // 保存元数据对应设置信息
    ArchiveMetaFieldMain entity = BeanUtil.copyProperties(req, ArchiveMetaFieldMain.class);
    archiveMetaFieldMainMapper.updateById(entity);

    // 保存元数据对应字段信息
    List<ArchiveMetaFieldDetailEditDTO> fieldList = req.getFieldList();
    Optional<ArchiveMetaFieldDetailEditDTO> any =
        fieldList.stream().filter(f -> !f.getFieldMainId().equals(entity.getId())).findAny();
    any.ifPresent(
        u ->
            BizTipException.throwException(
                ErrorCode.ARCHIVE_DATA_INVALIDED, "元数据对应修改，元数据字段与设置对应关系不正确"));
    // 更新设置
    List<ArchiveMetaFieldDetail> fieldDetailList =
        ConvertUtil.toList(fieldList, ArchiveMetaFieldDetail.class);
    archiveMetaFieldDetailSvc.saveOrUpdateBatch(fieldDetailList);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void remove(String ids) {
    Set<Long> idList = IdUtil.split(ids);
    this.baseMapper.deleteBatchIds(idList);
  }

  @Override
  public ArchiveMetaFieldMainVO view(Long id) {
    ArchiveMetaFieldMain entity = archiveMetaFieldMainMapper.selectById(id);
    return BeanUtil.copyProperties(entity, ArchiveMetaFieldMainVO.class);
  }

  @Override
  public List<Long> hasBeenSet(ArchiveMetaFieldMainQueryDTO req) {
    LambdaQueryWrapper<ArchiveMetaFieldMain> wrapper =
        Wrappers.<ArchiveMetaFieldMain>lambdaQuery()
            .eq(ArchiveMetaFieldMain::getArchTypeId, req.getArchTypeId())
            .eq(ArchiveMetaFieldMain::getSourceTableId, req.getSourceTableId())
            .eq(ArchiveMetaFieldMain::getDelFlag, DelFlagEnum.NO.getCode());
    List<ArchiveMetaFieldMain> list = list(wrapper);
    List<Long> collect =
        list.stream().map(ArchiveMetaFieldMain::getTargetArchTypeId).collect(Collectors.toList());
    collect.add(req.getArchTypeId());
    return collect;
  }
}
